Skip to content

Use Values to create and match value Exprs #10673

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

nicolasstucki
Copy link
Contributor

@nicolasstucki nicolasstucki commented Dec 7, 2020

Currently Expr(x) is used to create code that will produce a copy of the value. In extractors, it will take the code that creates a copy of the value and will create a copy of the value and return it. So far it was not always clear to everyone what is the difference between Expr(...) and '{...}. Using Value and constructor/extractor the intention of the code clearer.

  • Replace Expr.apply with Value.apply
  • Replace Expr.unapply with Value.unapply
  • Replace Exprs.unapply with Values.unapply
  • Aligns with expr.value and expr.valueOrError
  • Deprecate old definitions in 3.0.0-M3 and remove them in 3.0.0-RC1 for simpler migration
  • Add back deprecated Unlifted, unlift and unliftOrError to help migration from 3.0.0-M2 to 3.0.0-M3

Migration from 3.0.0.M2

// Create an expression that will create a copy of the value
- val expr = Expr(x)
+ val expr = Value(x)

// Create an `Option` of a copy of the value in the expression
- expr.unlift
+ expr.value

// Create a copy of the value in the expression or report an error
- expr.unliftedOrError
+ expr.valueOrError

// Match a value in an expression and recreate an expression that will create the same value
- expr match
-   case Unlifted(x) => Expr(x)
+ expr match
+   case Value(x) => Value(x)

// Matching nesteed values
- expr match
-   case '{ pow(${Unlifted(x)}, ${Unlifted(n)} } => Expr(pow(x, n)) 
+ expr match
+   case '{ pow(${Value(x)}, ${Value(n)} } => Value(pow(x, n)) 

// Extract varargs and get the value of each argument
- case '{ StringContext(${Varargs(partsExprs @ Unlifed(parts))}: _*) } =>
+ case '{ StringContext(${Varargs(partsExprs @ Values(parts))}: _*) } =>

@nicolasstucki nicolasstucki force-pushed the use-Value-for-Expr-creation-and-matching branch 3 times, most recently from d5a606b to 23282e9 Compare December 7, 2020 10:56
@nicolasstucki nicolasstucki added this to the 3.0.0-M3 milestone Dec 7, 2020
@nicolasstucki nicolasstucki added the release-notes Should be mentioned in the release notes label Dec 7, 2020
@nicolasstucki nicolasstucki marked this pull request as ready for review December 7, 2020 12:31
@liufengyun
Copy link
Contributor

  • Replace Expr.apply with Value.apply

I find it counter-intuitive with respect to Scala convention. In Scala, when we call C.apply, we construct a value of the type C.

@nicolasstucki
Copy link
Contributor Author

We do the same to create an Option[Int] using Some(3).

To be complete we could add type Value[+T] <: Expr[T]. This would imply that we could do something like

expr match
  case expr: Value[T] => expr.get
  case _ =>

But those operations would be more expensive at runtime than the current ones.

@nicolasstucki nicolasstucki force-pushed the use-Value-for-Expr-creation-and-matching branch from 23282e9 to ec9e8c0 Compare December 7, 2020 14:06
* Replace `Expr.apply` with `Value.apply`
* Replace `Expr.unapply` with `Value.unapply`
* Replace `Exprs.unapply` with `Values.unapply`
* Aligns with `expr.value` and `expr.valueOrError`
* Deprecate old definitions in 3.0.0-M3 and remove them in 3.0.0-RC1 for simpler migration
* Add back deprecated `Unlifted`, `unlift` and `unliftOrError` to help migration from 3.0.0-M2 to 3.0.0-M3
@nicolasstucki nicolasstucki force-pushed the use-Value-for-Expr-creation-and-matching branch from ec9e8c0 to 1d63579 Compare December 7, 2020 14:30
@deusaquilus
Copy link
Contributor

deusaquilus commented Dec 7, 2020

So now instead of:

def intValue: Expr[Int] = Expr(something)

It will be?

def intValue: Expr[Int] = Value(something)

This seems unnecessarily confusing. What is the motivation?

It seems this is one of those things that completely makes sense from the internals knowing the internals of the Tasty-Reflect API but it utterly confusing for a new user who might want to learn tasty macros.

@nicolasstucki
Copy link
Contributor Author

The motivation is that @liufengyun preferred Value instead of Expr to match on expressions containing values

expr match
  case '{ foo(${Value(x)})} => x

And we need to keep them in sync to avoid further confusion. I did not mind Expr.

@deusaquilus
Copy link
Contributor

Why can't you do something like Expr.Value for that? It seems like a special case for which it should not be necessary to change the entire API.

@nicolasstucki
Copy link
Contributor Author

It would be a bit too long for an operation that we use all the time.

@deusaquilus
Copy link
Contributor

deusaquilus commented Dec 7, 2020

Is there anything else you can do other then rename the Expr constructor? Any other thing you could possibly change the value-match API to? Knowing that 'Value' needs to be used to construct 'Expr' is really, really confusing to a new user that does not know Tasty-Reflect internals. I really want many people to be able to this API easily.

Right now it's just me annoying you about this stuff but in half a year when more people start using this API they'll start yelling about these things that will look like inconsistencies to them.

Literally, any solution for this is better other renaming the entire Expr-constructor API.

@nicolasstucki nicolasstucki removed the release-notes Should be mentioned in the release notes label Dec 7, 2020
@nicolasstucki nicolasstucki removed this from the 3.0.0-M3 milestone Dec 7, 2020
@nicolasstucki
Copy link
Contributor Author

I was not convinced by this change from the start. I promised I would try it out to find out if it was a good idea. It clearly has more drawbacks than what I originally anticipated. Thank you for all the feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants